MexicoMapsLink="https://github.com/AyeliAlp/ejercicicios_sem11/raw/main/maps/mexicoMaps_6366.gpkg"

from  fiona import listlayers


#layers in maps
listlayers(MexicoMapsLink)
['country',
'cities',
'rivers',
'border',
'airports',
'states',
'municipalities']
#Realizamos la lectura de los datos:

import os
os.environ['USE_PYGEOS'] = '0'

import geopandas as gpd

states=gpd.read_file(MexicoMapsLink,layer='states')
municipalities=gpd.read_file(MexicoMapsLink,layer='municipalities')
airports=gpd.read_file(MexicoMapsLink,layer='airports')
rivers=gpd.read_file(MexicoMapsLink,layer='rivers')
border=gpd.read_file(MexicoMapsLink,layer='border')
#Primero descargamos informacion importante sobre los principales puertos y terminales a nivel mundial
#y los leemos
import pandas as pd 
infoseaports=pd.read_csv(os.path.join("data","UpdatedPub150.csv"))

#columns available (so many)
infoseaports.columns.to_list()
['World Port Index Number',
'Region Name',
'Main Port Name',
'Alternate Port Name',
'UN/LOCODE',
'Country Code',
'World Water Body',
'IHO S-130 Sea Area',
'Sailing Direction or Publication',
'Publication Link',
'Standard Nautical Chart',
'IHO S-57 Electronic Navigational Chart',
'IHO S-101 Electronic Navigational Chart',
'Digital Nautical Chart',
'Tidal Range (m)',
'Entrance Width (m)',
'Channel Depth (m)',
'Anchorage Depth (m)',
'Cargo Pier Depth (m)',
'Oil Terminal Depth (m)',
'Liquified Natural Gas Terminal Depth (m)',
'Maximum Vessel Length (m)',
'Maximum Vessel Beam (m)',
'Maximum Vessel Draft (m)',
'Offshore Maximum Vessel Length (m)',
'Offshore Maximum Vessel Beam (m)',
'Offshore Maximum Vessel Draft (m)',
'Harbor Size',
'Harbor Type',
'Harbor Use',
'Shelter Afforded',
'Entrance Restriction - Tide',
'Entrance Restriction - Heavy Swell',
'Entrance Restriction - Ice',
'Entrance Restriction - Other',
'Overhead Limits',
'Underkeel Clearance Management System',
'Good Holding Ground',
'Turning Area',
'Port Security',
'Estimated Time of Arrival Message',
'Quarantine - Pratique',
'Quarantine - Sanitation',
'Quarantine - Other',
'Traffic Separation Scheme',
'Vessel Traffic Service',
'First Port of Entry',
'US Representative',
'Pilotage - Compulsory',
'Pilotage - Available',
'Pilotage - Local Assistance',
'Pilotage - Advisable',
'Tugs - Salvage',
'Tugs - Assistance',
'Communications - Telephone',
'Communications - Telefax',
'Communications - Radio',
'Communications - Radiotelephone',
'Communications - Airport',
'Communications - Rail',
'Search and Rescue',
'NAVAREA',
'Facilities - Wharves',
'Facilities - Anchorage',
'Facilities - Dangerous Cargo Anchorage',
'Facilities - Med Mooring',
'Facilities - Beach Mooring',
'Facilities - Ice Mooring',
'Facilities - Ro-Ro',
'Facilities - Solid Bulk',
'Facilities - Liquid Bulk',
'Facilities - Container',
'Facilities - Breakbulk',
'Facilities - Oil Terminal',
'Facilities - LNG Terminal',
'Facilities - Other',
'Medical Facilities',
'Garbage Disposal',
'Chemical Holding Tank Disposal',
'Degaussing',
'Dirty Ballast Disposal',
'Cranes - Fixed',
'Cranes - Mobile',
'Cranes - Floating',
'Cranes - Container',
'Lifts - 100+ Tons',
'Lifts - 50-100 Tons',
'Lifts - 25-49 Tons',
'Lifts - 0-24 Tons',
'Services - Longshoremen',
'Services - Electricity',
'Services - Steam',
'Services - Navigation Equipment',
'Services - Electrical Repair',
'Services - Ice Breaking',
'Services - Diving',
'Supplies - Provisions',
'Supplies - Potable Water',
'Supplies - Fuel Oil',
'Supplies - Diesel Oil',
'Supplies - Aviation Fuel',
'Supplies - Deck',
'Supplies - Engine',
'Repairs',
'Dry Dock',
'Railway',
'Latitude',
'Longitude']
#Primero reenombramos la columna Main Port Name a portName. Luego, obtenemos la información
#general y resumida sobre el DataFrame
infoseaports.rename(columns={'Main Port Name':'portName'},inplace=True)
infoseaports=infoseaports.loc[:,['portName''Country Code','Latitude''Longitude']]
infoseaports.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 3774 entries, 0 to 3773
Data columns (total 4 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 portName 3774 non-null object
1 Country Code 3774 non-null object
2 Latitude 3774 non-null float64
3 Longitude 3774 non-null float64
dtypes: float64(2), object(2)
memory usage: 118.1+ KB
#Ahora creamos un nuevo GeoDataFrame llamado "seaports". Además generamos una geometria de puntos a partir de la
#columnas de longitud y latitud. Como podemos notar, no está proyectado. Luego, transformamos los datos de 
#seaports_mex al sistema de referencia de coordenadas proyectado con codigo 6366 
seaports=gpd.GeoDataFrame(data=infoseaports.copy(),
                 geometry=gpd.points_from_xy(infoseaports.Longitude,
                                             infoseaports.Latitude), 
                 crs=4326)# notice it is unprojected

seaports_mex=seaports[seaports['Country Code']=='Mexico'].copy()

seaports_mex.reset_index(drop=Trueinplace=True)

seaports_mex_6366=seaports_mex.to_crs(6366# projected crs
#Creamos un nuevo DataFrame llamado largeAirports seleccionando "airports" donde el valor de la columna
#"kind" es "large_airport". Luego, graficamos los aeropuertos que se representan como triangulos rojos
#y los punto celestes representan a los puertos maritimos de mexico.
# subsetting
largeAirports=airports[airports.kind=='large_airport'
largeAirports.reset_index(drop=Trueinplace=True)

#plotting
base=largeAirports.plot(color='red',marker="^")
seaports_mex_6366.plot(ax=base,alpha=0.5,markersize=3)
<Axes: >
#Exercise 1
#Create two sets of points.

#Compute the distance matrix for both sets.

#Select one row of the distance matrix, and plot the two point with the minimal distance
#Distance
#Between points
#The easiest way to understand distance is to compute how far two coordinates are from each other.

#Visualizamos los puertos maritimos de Mexico:

seaports_mex_6366.head()
#Visualizamos los aeropuertos grandes de Mexico:

largeAirports.head()
#Si ambos GeoDataFrame tienen en el mismo crs proyectado, podemos usar la funcion distancia:

#Calculamos la distancia en kilometros entre la geometria del primer aeropuerto grande que aparece 
#en el DataFrame y la geometria del primer puerto del DataFrame "seaports_mex_6366"
largeAirports.iloc[0].geometry.distance(seaports_mex_6366.iloc[0].geometry)/1000
2602.4465202278006
#Calculamos todas las distancias entre cada geometria de los puertos y todas las geometrias de los
#aeropuertos en km:

#Prueba 1
seaports_mex_6366.geometry.apply\
(lambda g: largeAirports.geometry.distance(g)/1000)
#Aaui tambien calculamos las distancias pero esta vez utilizamos los nombres de los puertos y aeropuertos como indices
#para realizar la comparación, en km.
#Prueba 2
seaports_mex_6366.set_index('portName').geometry.apply\
(lambda g: largeAirports.set_index('name').geometry.distance(g)/1000)
#calculamos las distancias en kilómetros entre cada puerto en seaports_mex_6366 y todos los aeropuertos en largeAirports, utilizando 
#los nombres como índices para realizar la comparación. Luego, ordenamos los resultados por los nombres de los puertos y 
#los nombres de los aeropuertos, tanto en las filas como en las columnas.
#Prueba 3
seaports_mex_6366.set_index('portName').geometry.apply\
(lambda g: largeAirports.set_index('name').geometry.distance(g)/1000).\
sort_index(axis=0).sort_index(axis=1)
#Nos quedamos con la prueba:
#Calculamos una matriz de distancias en kilómetros entre cada puerto en seaports_mex_6366 y todos los aeropuertos en largeAirports, 
#utilizando los nombres como índices para realizar la comparación. La matriz resultante está ordenada por los nombres de los puertos 
#y los nombres de los aeropuertos, tanto en las filas como en las columnas, y le asignamos la variable distanceMatrixKM_sea_air.

distanceMatrixKM_sea_air= seaports_mex_6366.set_index('portName').geometry.apply\
                          (lambda g: largeAirports.set_index('name').geometry.distance(g)/1000).\
                          sort_index(axis=0).sort_index(axis=1)
#Este es un marco de datos (pandas), y las instalaciones son índices de fila y columna. Esto es útil de esta manera:

#calculamos el promedio de las distancias en kilómetros entre cada puerto en seaports_mex_6366 y los aeropuertos en largeAirports, y luego mostr 
#los puertos ordenados en función de sus distancias promedio de menor a mayor
distanceMatrixKM_sea_air.mean(axis=1).sort_values(ascending=True)
#Calcuamos el promedio de las distancias para cada puerto, la distancia minima para cada puerto y 
#la distancia maxima para cada puerto:

SomeStats=pd.DataFrame()
SomeStats['mean']=distanceMatrixKM_sea_air.mean(axis=1)
SomeStats['min']=distanceMatrixKM_sea_air.min(axis=1)
SomeStats['max']=distanceMatrixKM_sea_air.max(axis=1)
SomeStats.head()
#También podemos usar idxmax para obtener las ubicaciones particulares:

#Buscamos el indice del valor maximo en cada fila de la matriz de distancia
#(aeropuerto más lejano a cada puerto marítimo) 
distanceMatrixKM_sea_air.idxmax(axis="columns")
#puerto marítimo más lejano a cada aeropuerto 
distanceMatrixKM_sea_air.idxmax(axis="rows")
#aeropuerto más cercano a cada puerto de mar
distanceMatrixKM_sea_air.idxmin(axis="columns")
#puerto marítimo más cercano a cada aeropuerto
distanceMatrixKM_sea_air.idxmin(axis="rows")
#Ejercicio 2
#Crear un conjunto de puntos y un conjunto de líneas.

#Calcule la matriz de distancias para ambos conjuntos.

#Seleccione una línea de la matriz de distancia y trace el punto más cercano y el más lejano a esa línea.
#Distancia entre línea y punto
#Visualizamos los rios que tenemos:

rivers
#Mantenemos uno:

rivers[rivers.NAME.str.contains('Grande')]
#Puedes ver que la distancia funciona entre estos dos elementos::

rivers[rivers.NAME.str.contains('Grande')].iloc[0].geometry.distance(largeAirports.geometry)
#Basándonos en lo que hicimos anteriormente, calculemos todas las distancias en kilómetros entre cada río en rivers y todos los aeropuertos en largeAirports, 
#utilizando los nombres de los ríos y los aeropuertos como índices.

distanceMatrixKM_riv_air=rivers.set_index('NAME').geometry.apply\
(lambda g: largeAirports.set_index('name').geometry.distance(g)/1000).\
sort_index(axis=0).sort_index(axis=1)
distanceMatrixKM_riv_air
#Aquí, vemos una fila (río), que indica la distancia a cada columna (aeropuerto grande):
distanceMatrixKM_riv_air.loc['Rio Grande, North America'].sort_values()
#Graficamos:

base=rivers[rivers.NAME.str.contains('Grande')].explore()
largeAirports.explore(m=base,color='red',marker_kwds=dict(radius=10))
#Nos centramos en los que pertenecen a un sistema, pero al correr el digo estos datos no presentan informacion sobre 
#quienes pertenecen a un sistema 

rivers[~rivers.SYSTEM.isna()]
#Disolvemos los que pertenecen a un sistema en una multilínea:

systems=rivers.dissolve(by='SYSTEM')
systems
#Creamos una nueva columna que contenga los nombres de los sistemas que contiene los nombres de los sistemas:

# format the GDF:
systems['NAME']=systems.index
systems.reset_index(drop=True,inplace=True)
systems
#Calculamos la matriz de distancia en kilometros entre los sistemas y los grandes aeropuertos.
#Pero como no presentamos informacion de sistema, el codigo nos arrojará un error.

distanceMatrixKM_sys_air=systems.set_index('NAME').geometry.apply\
(lambda g: largeAirports.set_index('name').geometry.distance(g)/1000).\
sort_index(axis=0).sort_index(axis=0)

distanceMatrixKM_sys_air
#Obtenemos las minimas distancias:

mins=distanceMatrixKM_sys_air.idxmin(axis="columns")
mins
TypeError: '>=' not supported between instances of 'str' and 'int'
#Visualizamos uno de llos
mins[1]
NameError: name 'mins' is not defined
#Visualizamos de manera interactiva los sistemas del DataFrame "systems". Luego, mostramos dos visualzaciones
#adicioanles para resaltar los aeropuertos que son mas cercanos y los que no son las mas cercanos del sistema.
base=systems.explore()
# the closest
largeAirports[largeAirports.name.isin(mins)].explore(m=base,color='red',marker_kwds=dict(radius=10))
# the NOT closest
largeAirports[~largeAirports.name.isin(mins)].explore(m=base,color='blue',marker_kwds=dict(radius=5))
ValueError: Location values cannot contain NaNs.
#Ejercicio 3
#Crear un conjunto de puntos y un conjunto de polígonos
#Calcule la matriz de distancias para ambos conjuntos.
#Seleccione un polígono de la matriz de distancia y trace el punto más cercano y el más lejano a ese polígono.
#Creamos un poligono convexo del DataFrame de systems:

systems.convex_hull.plot()
<Axes: >
/opt/python/envs/default/lib/python3.8/site-packages/geopandas/plotting.py:409: UserWarning: The GeoSeries you are attempting to plot is empty. Nothing has been displayed.
warnings.warn(
#Ahora, un GDF para los cascos:

systems_hulls=systems.convex_hull.to_frame()
systems_hulls['system']=['''']
systems_hulls.rename(columns={0:'geometry'},inplace=True)
systems_hulls=systems_hulls.set_geometry('geometry')
systems_hulls.crs="EPSG:6366"
systems_hulls
NameError: name 'systems' is not defined
#Calculamos la matriz de distancia:

distanceMatrixKM_sysHull_air=systems_hulls.set_index('system').geometry.apply\
(lambda g: largeAirports.set_index('name').geometry.distance(g)/1000).\
sort_index(axis=0).sort_index(axis=1)

distanceMatrixKM_sysHull_air
TypeError: (<class 'geopandas.geoseries.GeoSeries'>, <class 'NoneType'>)
#Las diferencias minimas :

mins=distanceMatrixKM_sysHull_air.idxmin(axis="columns")
mins
NameError: name 'distanceMatrixKM_sysHull_air' is not defined
#Graficamos
base=systems_hulls.explore()
largeAirports[largeAirports.name.isin(mins)].explore(m=base,color='red',marker_kwds=dict(radius=10))
largeAirports[~largeAirports.name.isin(mins)].explore(m=base,color='blue',marker_kwds=dict(radius=5))
ValueError: Location values cannot contain NaNs.
/opt/python/envs/default/lib/python3.8/site-packages/geopandas/array.py:968: RuntimeWarning: All-NaN slice encountered
np.nanmin(b[:, 0]), # minx
/opt/python/envs/default/lib/python3.8/site-packages/geopandas/array.py:969: RuntimeWarning: All-NaN slice encountered
np.nanmin(b[:, 1]), # miny
/opt/python/envs/default/lib/python3.8/site-packages/geopandas/array.py:970: RuntimeWarning: All-NaN slice encountered
np.nanmax(b[:, 2]), # maxx
/opt/python/envs/default/lib/python3.8/site-packages/geopandas/array.py:971: RuntimeWarning: All-NaN slice encountered
np.nanmax(b[:, 3]), # maxy
#Ejercicio 4
#Crear un conjunto de puntos y un conjunto de líneas.

#Obtenga el búfer para las líneas, seleccione diferentes valores para la distancia.

#Mantenga los puntos que están dentro del búfer (como en el punto 2, debe jugar con diferentes distancias hasta que muestre algo interesante).
#Uso de búferes
#Un caso muy importante en el análisis de distancias es el uso de buffers:

#Recordamos el DataFrame que creamos hace un momento:
distanceMatrixKM_riv_air
#Obtenemos el valor de Colorado
distanceMatrixKM_riv_air.loc['Colorado'].min()
192.39775507831118
#Creamos un buffer con cualquier valor, en este caso utilizamos Colorado:

minMts=distanceMatrixKM_riv_air.loc['Colorado'].min()*1000

#El buffer es un poligono:
rivers[rivers.NAME=='Colorado'].buffer(distance = minMts)
#Visualizamos el buffer:
bufferAroundColorado=rivers[rivers.NAME=='Colorado'].buffer(distance = minMts)
bufferAsBase=bufferAroundColorado.explore(color='red')
rivers[rivers.NAME=='Colorado'].explore(m=bufferAsBase,color='blue',style_kwds={'weight':0.5})
#Al buffer le agregaremos una capa de aeropuertos pequeños:

small_airports=airports[airports.kind=='small_airport']

# plotting
rivers[rivers.NAME=='Colorado'].explore(m=bufferAsBase,color='blue',style_kwds={'weight':0.5})
small_airports.explore(m=bufferAsBase,color='black')
#Ahora, podemos usar el buffer (polígono) para mantener los aeropuertos que están a esa distancia particular alrededor del río:

riversWithinBuffer=small_airports.clip(mask=bufferAroundColorado)
#
riversWithinBuffer
#Visualizamos interactivamente al buffer alrededor del rio colorado en rojo, el rio Colorado en azul
#y los rios dentro del buffer en negro
bufferAsBase=bufferAroundColorado.explore(color='red')
rivers[rivers.NAME=='Colorado'].explore(m=bufferAsBase,color='blue',style_kwds={'weight':0.5})
riversWithinBuffer.explore(m=bufferAsBase,color='black')
#Calculamos el mínimo de todos los mínimos por fila 
distanceMatrixKM_riv_air.min(axis=1).min() 
192.39775507831118
#Usamos el valor anterior y realizamos una visualizacion intercativa que incluye un buffer alrededor de los rios en el DataFrame "rivers" 
#resaltado en rojo. Tambien se visualizarán los rios en azul y los aeropuertos en negro. 
minMinMts_5=5*distanceMatrixKM_riv_air.min(axis=1).min()*1000


allMinBuffer=rivers.buffer(distance = minMinMts_5).explore(color='red')
rivers.explore(m=allMinBuffer,color='blue',style_kwds={'weight':0.5})
small_airports.explore(m=allMinBuffer,color='black')
#Vemos todos los poligonos de buffer:
rivers.buffer(distance = minMinMts_5)
#Verificamos el tipo
riversAll_buf=rivers.buffer(distance = minMinMts_5)
type(riversAll_buf)
geopandas.geoseries.GeoSeries
#Formateamos:
riversAll_bufDF=riversAll_buf.to_frame()
riversAll_bufDF.rename(columns={0:'geometry'},inplace=True)
riversAll_bufDF = riversAll_bufDF.set_geometry("geometry")
riversAll_bufDF.crs
<Projected CRS: EPSG:6366>
Name: Mexico ITRF2008 / UTM zone 11N
Axis Info [cartesian]:
- E[east]: Easting (metre)
- N[north]: Northing (metre)
Area of Use:
- name: Mexico west of 114°W, onshore and offshore.
- bounds: (-122.19, 15.01, -114.0, 32.72)
Coordinate Operation:
- name: UTM zone 11N
- method: Transverse Mercator
Datum: Mexico ITRF2008
- Ellipsoid: GRS 1980
- Prime Meridian: Greenwich
#Hacemos un recorte entre las capas small_airports y riversAll_bufDF, y luego guarda el resultado en el DataFrame allRiversWithinBuffs
allRiversWithinBuffs=small_airports.clip(riversAll_bufDF)
allRiversWithinBuffs
#Graficamos
base=riversAll_bufDF.plot(color='yellow')
allRiversWithinBuffs.plot(ax=base, color='green'markersize=1)
<Axes: >
#Graficamos de manera interactiva

base=riversAll_bufDF.explore(color='yellow')
allRiversWithinBuffs.explore(m=base, color='green')
Created using Figma